package com.sansan.qiangji.realize.warehouse;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sansan.qiangji.VO.warehouse.pullOrder.PullOrderBoxDetailVO;
import com.sansan.qiangji.VO.warehouse.pullOrder.PullOrderDetailVO;
import com.sansan.qiangji.VO.warehouse.pullOrder.PullOrderListResultVO;
import com.sansan.qiangji.VO.warehouse.pullOrder.PullOrderVO;
import com.sansan.qiangji.dto.PullOrderDetailExcelDto;
import com.sansan.qiangji.dto.PullOrderExcelDto;
import com.sansan.qiangji.entity.base.Product;
import com.sansan.qiangji.entity.warehouse.PullOrder;
import com.sansan.qiangji.entity.warehouse.PullOrderBoxDetail;
import com.sansan.qiangji.entity.warehouse.PullOrderDetail;
import com.sansan.qiangji.entity.warehouse.example.PullOrderBoxDetailExample;
import com.sansan.qiangji.entity.warehouse.example.PullOrderDetailExample;
import com.sansan.qiangji.entity.warehouse.example.PullOrderExample;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.warehouse.PullOrderAddForm;
import com.sansan.qiangji.form.warehouse.PullOrderEditForm;
import com.sansan.qiangji.form.warehouse.PullOrderListForm;
import com.sansan.qiangji.service.impl.base.ProductServiceImpl;
import com.sansan.qiangji.service.inter.warehouse.PullOrderBoxDetailService;
import com.sansan.qiangji.service.inter.warehouse.PullOrderDetailService;
import com.sansan.qiangji.service.inter.warehouse.PullOrderService;
import com.sansan.qiangji.utils.DateUtil;
import com.sansan.qiangji.utils.StringUtil;
import com.sansan.qiangji.utils.pageUtils.PageResult;
import com.sansan.qiangji.utils.pageUtils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PullOrderReal {

    @Autowired
    private PullOrderService pullOrderService;
    @Autowired
    private PullOrderDetailService pullOrderDetailService;
    @Autowired
    private PullOrderBoxDetailService pullOrderBoxDetailService;
    @Autowired
    private ProductServiceImpl productService;


    @Transactional
    public void deletePullOrder(Integer pullOrderId) {
        PullOrder pullOrder = pullOrderService.selectByPrimaryKey(pullOrderId);
        if (pullOrder == null) {
            log.error("【入库单删除】入库单不存在，pullOrderId={}", pullOrderId);
            throw new ServiceException(ResultEnum.PULL_ORDER_IS_NOT_EXIST);
        }
        int row = pullOrderService.deleteByPrimaryKey(pullOrderId);
        if (row == 0) {
            log.error("【入库单删除】入库单删除失败，pullOrderId={}", pullOrderId);
            throw new ServiceException(ResultEnum.PULL_ORDER_DELETE_ERROR);
        }
    }

    @Transactional
    public void addPullOrder(PullOrderAddForm pullOrderAddForm) {
        PullOrderExample pullOrderExample = new PullOrderExample();
        pullOrderExample.or().andBatchNumberEqualTo(pullOrderAddForm.getBatchNumber());
        List<PullOrder> pullOrders = pullOrderService.selectByExample(pullOrderExample);
        if (pullOrders.size() != 0) {
            log.error("【出库单导入】出库单批次已存在");
            throw new ServiceException(ResultEnum.PULL_ORDER_BATCH_NUMBER_EXIST);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        //自动生成入库单号
        String code = StringUtil.codeGenerater("pull");
        PullOrder pullOrder = new PullOrder();
        BeanUtils.copyProperties(pullOrderAddForm, pullOrder);
        pullOrder.setPullOrderCode(code);
        pullOrder.setPullOrderStatus("未出库");
        pullOrder.setPullOrderOwn(request.getAttribute("userName").toString());
        pullOrder.setPullOrderCheck("");
        pullOrder.setCheckStatus("未审核");
        int row = pullOrderService.insert(pullOrder);
        if (row == 0) {
            log.error("【入库单新增】入库单新增失败");
            throw new ServiceException(ResultEnum.PULL_ORDER_INSERT_ERROR);
        }
    }


    @Transactional
    public void editPullOrder(PullOrderEditForm pullOrderEditForm) {
        PullOrder pullOrder = new PullOrder();
        PullOrder order = pullOrderService.selectByPrimaryKey(pullOrderEditForm.getPullOrderId());
        BeanUtils.copyProperties(pullOrderEditForm, pullOrder);
        pullOrder.setPullOrderCode(order.getPullOrderCode());
        int row = pullOrderService.updateByPrimaryKey(pullOrder);
        if (row == 0) {
            log.error("【入库单新增】入库单新增失败");
            throw new ServiceException(ResultEnum.PULL_ORDER_INSERT_ERROR);
        }
    }

    public PullOrderListResultVO pullOrderList(PullOrderListForm pullOrderListForm) {
        PullOrderExample example = new PullOrderExample();
        PullOrderExample.Criteria criteria = example.createCriteria();
        if (pullOrderListForm.getPullOrderCode() != null && !"".equals(pullOrderListForm.getPullOrderCode())) {
            criteria.andPullOrderCodeLike("%" + pullOrderListForm.getPullOrderCode() + "%");
        }
        if (pullOrderListForm.getBatchNumber() != null && !"".equals(pullOrderListForm.getBatchNumber())) {
            criteria.andBatchNumberLike("%" + pullOrderListForm.getBatchNumber() + "%");
        }
        if (pullOrderListForm.getPullOrderStatus() != null && !"".equals(pullOrderListForm.getPullOrderStatus())) {
            criteria.andPullOrderStatusLike(pullOrderListForm.getPullOrderStatus());
        }
        if (pullOrderListForm.getPullOrderOwn() != null && !"".equals(pullOrderListForm.getPullOrderOwn())) {
            criteria.andPullOrderOwnLike("%" + pullOrderListForm.getPullOrderOwn() + "%");
        }
        if (pullOrderListForm.getQueryTime() != null && pullOrderListForm.getQueryTime().size() != 0) {
            String startTime = pullOrderListForm.getQueryTime().get(0) + " 00:00:00";
            String endTime = pullOrderListForm.getQueryTime().get(1) + " 23:59:59";
            Date start = DateUtil.string2Date(startTime, "yyyy-MM-dd HH:mm:ss");
            Date end = DateUtil.string2Date(endTime, "yyyy-MM-dd HH:mm:ss");
            criteria.andPullOrderCreatimeBetween(start, end);
        }
        example.setOrderByClause("pull_order_creatime desc");
        int pageNum = pullOrderListForm.getPageNum();
        int pageSize = pullOrderListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        List<PullOrder> pullOrderList = pullOrderService.selectByExample(example);
        PageResult<PullOrder> pullOrderPageResult = PageUtil.getPageResult(new PageInfo<>(pullOrderList));
        PullOrderListResultVO pullOrderListResultVO = new PullOrderListResultVO();
        BeanUtils.copyProperties(pullOrderPageResult, pullOrderListResultVO);
        List<PullOrderVO> pullOrderVOS = new ArrayList<>();
        for (PullOrder pullOrder : pullOrderPageResult.getContent()) {
            PullOrderVO pullOrderVO = new PullOrderVO();
            BeanUtils.copyProperties(pullOrder, pullOrderVO);
            //查找出库单详情
            PullOrderDetailExample pullOrderDetailExample = new PullOrderDetailExample();
            pullOrderDetailExample.or().andPullOrderCodeEqualTo(pullOrder.getPullOrderCode());
            List<PullOrderDetail> pullOrderDetails = pullOrderDetailService.selectByExample(pullOrderDetailExample);
            List<PullOrderDetailVO> pullOrderDetailVOS = new ArrayList<>();
            for (PullOrderDetail pullOrderDetail : pullOrderDetails) {
                PullOrderDetailVO pullOrderDetailVO = new PullOrderDetailVO();
                BeanUtils.copyProperties(pullOrderDetail, pullOrderDetailVO);
                //查找箱子详情
                PullOrderBoxDetailExample pullOrderBoxDetailExample = new PullOrderBoxDetailExample();
                pullOrderBoxDetailExample.or().andPullOrderDetailCodeEqualTo(pullOrderDetail.getPullOrderDetailCode());
                List<PullOrderBoxDetail> boxDetails = pullOrderBoxDetailService.selectByExample(pullOrderBoxDetailExample);
                List<PullOrderBoxDetailVO> boxDetailVOS = new ArrayList<>();
                for (PullOrderBoxDetail boxDetail : boxDetails) {
                    PullOrderBoxDetailVO pullOrderBoxDetailVO = new PullOrderBoxDetailVO();
                    BeanUtils.copyProperties(boxDetail, pullOrderBoxDetailVO);
                    boxDetailVOS.add(pullOrderBoxDetailVO);
                }
                pullOrderDetailVO.setPullOrderBoxDetailVOS(boxDetailVOS);
                pullOrderDetailVOS.add(pullOrderDetailVO);
            }

            pullOrderVO.setPullOrderDetailVOS(pullOrderDetailVOS);
            pullOrderVOS.add(pullOrderVO);
        }
        pullOrderListResultVO.setPullOrderVOS(pullOrderVOS);
        return pullOrderListResultVO;
    }

    public List<PullOrderDetailExcelDto> getAllPullOrderDto(String pullOrderCode){
        PullOrderDetailExample pullOrderDetailExample = new PullOrderDetailExample();
        pullOrderDetailExample.or().andPullOrderCodeEqualTo(pullOrderCode);
        List<PullOrderDetail> pullOrderDetails = pullOrderDetailService.selectByExample(pullOrderDetailExample);
        List<PullOrderDetailExcelDto> pullOrderExcelDtos = new ArrayList<>();
        for (PullOrderDetail pullOrderDetail : pullOrderDetails){
            PullOrderDetailExcelDto pullOrderExcelDto = new PullOrderDetailExcelDto();
            BeanUtils.copyProperties(pullOrderDetail, pullOrderExcelDto);
            pullOrderExcelDtos.add(pullOrderExcelDto);
        }
        return pullOrderExcelDtos;
    }

    public List<PullOrderDetailExcelDto> getAllPullOrderDtoByDate(Date startTime, Date endTime){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endTime);
        calendar.add(Calendar.DATE, 1);
        endTime = calendar.getTime();
        PullOrderDetailExample pullOrderDetailExample = new PullOrderDetailExample();
        pullOrderDetailExample.or().andCreateTimeBetween(startTime, endTime);
        List<PullOrderDetail> pullOrderDetails = pullOrderDetailService.selectByExample(pullOrderDetailExample);
        List<PullOrderDetailExcelDto> pullOrderExcelDtos = new ArrayList<>();
        for (PullOrderDetail pullOrderDetail : pullOrderDetails){
            PullOrderDetailExcelDto pullOrderExcelDto = new PullOrderDetailExcelDto();
            BeanUtils.copyProperties(pullOrderDetail, pullOrderExcelDto);
            pullOrderExcelDtos.add(pullOrderExcelDto);
        }
        return pullOrderExcelDtos;
    }

    @Transactional
    public void uploadPullOrderExcel(List<PullOrderExcelDto> pullOrderExcelDtos){
        List<Product> products = new ArrayList<>();
        PullOrderExample pullOrderExample = new PullOrderExample();
        pullOrderExample.or().andBatchNumberEqualTo(pullOrderExcelDtos.get(0).getBatchNumber());
        List<PullOrder> pullOrders = pullOrderService.selectByExample(pullOrderExample);
        if (pullOrders.size() != 0){
            log.error("【出库单导入】出库单批次已存在");
            throw new ServiceException(ResultEnum.PULL_ORDER_BATCH_NUMBER_EXIST);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        for (PullOrderExcelDto pullOrderExcelDto : pullOrderExcelDtos){
            Product product = new Product();
            BeanUtils.copyProperties(pullOrderExcelDto, product);
            products.add(product);
        }
        // 自动添加物料基础信息
        List<Product> productList = productService.selectProducts(products);
        for (Product product : productList){
            List<Product> products1 = products.stream().filter(e->e.getProductName().equals(product.getProductName())||e.getProductCode().equals(product.getProductCode())).collect(Collectors.toList());
            if (products1.size()!=0){
                if (!product.getProductCode().equals(products1.get(0).getProductCode())||!product.getProductName().equals(products1.get(0).getProductName())){
                    List<PullOrderExcelDto> pullOrderExcelDtoList = pullOrderExcelDtos.stream().filter(e->e.getProductCode().equals(products1.get(0).getProductCode())).collect(Collectors.toList());
                    int rowIndex = -1;
                    if (pullOrderExcelDtoList.size()!=0){
                        if (pullOrderExcelDtoList.get(0).getPullOrderIndex() != null){
                            rowIndex = pullOrderExcelDtoList.get(0).getPullOrderIndex();
                        }
                    }
                    log.error("【入库单导入】物料编号、物料名称与物料基础信息不匹配");
                    throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_SAME_WITH_BASE.getCode(), "第 "+ rowIndex +" 行 物料编号、物料名称与物料基础信息不匹配！");
                }
                products.remove(products1.get(0));
            }
        }
        if (products.size()!=0){
            productService.insertProducts(products);
        }
        // 生成出库单
        PullOrder pullOrder = new PullOrder();
        String pullOrderCode = StringUtil.codeGenerater("pull");
        pullOrder.setPullOrderCode(pullOrderCode);
        pullOrder.setBatchNumber(pullOrderExcelDtos.get(0).getBatchNumber());
        pullOrder.setPullOrderStatus("未出库");
        pullOrder.setPullOrderCreatime(new Date());
        pullOrder.setPullOrderCheck("");
        pullOrder.setCheckStatus("未审核");
        pullOrder.setPullOrderOwn(request.getAttribute("userName").toString());
        pullOrderService.insert(pullOrder);
        // 生成入库详情单
        List<PullOrderDetail> pullOrderDetails = new ArrayList<>();
        String pullOrderDetailCode = StringUtil.codeGenerater("pull_detail");
        int i = 0;
        for (PullOrderExcelDto pullOrderExcelDto : pullOrderExcelDtos){
            PullOrderDetail pullOrderDetail = new PullOrderDetail();
            BeanUtils.copyProperties(pullOrderExcelDto, pullOrderDetail);
            pullOrderDetail.setPullOrderCode(pullOrderCode);
            pullOrderDetail.setPullOrderDetailCode(pullOrderDetailCode + String.format("%03d", i));
            pullOrderDetail.setProductPullPace("进行中");
            pullOrderDetail.setPullOrderCount(Integer.parseInt(pullOrderExcelDto.getUnintCount()));
            pullOrderDetail.setBatchNumber(pullOrderExcelDtos.get(0).getBatchNumber());
            List<Product> products1 = productList.stream().filter(e->e.getProductCode().equals(pullOrderExcelDto.getProductCode())).collect(Collectors.toList());
            pullOrderDetail.setCountBox(0);
            if (products1.size() !=0){
                pullOrderDetail.setCountBox(products1.get(0).getCountBox());
            }
            pullOrderDetail.setCreateTime(new Date());
            pullOrderDetails.add(pullOrderDetail);
            i++;
        }
        pullOrderDetailService.insertPullOrderDetails(pullOrderDetails);
    }
}
